package com.learn.rpc.version.version4;

import com.learn.rpc.common.AdminUser;
import com.learn.rpc.common.FinalParam;
import com.learn.rpc.common.IAdminUserService;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

/**
 * 使用代理+反射的方式将指定类的全部方法进行远程调用,实现一个类一个代理就能全部访问远程所有方法
 * 还不能支持所有的类,只能一个类写一次
 * @author wangxing
 * @version 2020/8/15 7:03 Administrator
 */
public class RpcClient {
    public static void main(String[] args) throws IOException {
       IAdminUserService service = Stud.getStudIAdminUserService();
        System.out.println(service.findAdminUserById(12553));
        System.out.println(service.findAdminUserByName("wangxing"));
        System.out.println(service.getNameAndId(1234, "KingStar"));
    }
}

class Stud {
    static InvocationHandler h = new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Socket socket = new Socket(FinalParam.HOST,FinalParam.PORT);

            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            String methodName = method.getName();
            Class<?>[] parameterTypes = method.getParameterTypes();
            objectOutputStream.writeUTF(methodName);
            objectOutputStream.writeObject(parameterTypes);
            objectOutputStream.writeObject(args);
            objectOutputStream.flush();

            ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
            Object o = objectInputStream.readObject();

            objectInputStream.close();
            objectOutputStream.close();
            socket.close();

            return o;
        }
    };
    public static IAdminUserService getStudIAdminUserService() {
        IAdminUserService service = (IAdminUserService) Proxy.newProxyInstance(IAdminUserService.class.getClassLoader(),new Class[]{IAdminUserService.class},h);
        return service;
    }
}
